package ar.uade.distribuidas.tpo.dba.dominio;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import ar.uade.distribuidas.tpo.base.dominiodto.EstadoRemito;
import ar.uade.distribuidas.tpo.base.dominiodto.ItemRemitoDTO;
import ar.uade.distribuidas.tpo.base.dominiodto.RemitoDTO;


@Entity
@Table(name = "remitos")
public class Remito {
	@Id
	private int numero;
	@OneToOne
	private Cliente cliente;
	
	@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
	@JoinColumn(name="id_Remito")
	private List<ItemRemito> itemsRemito;
	
	@Enumerated(EnumType.STRING)
	private EstadoRemito estado;
	private String fecha;

	public Remito(int numero, Cliente cliente, EstadoRemito estado, String fecha) {
		super();
		this.numero = numero;
		this.cliente = cliente;
		this.itemsRemito = new ArrayList<ItemRemito>();
		this.estado = estado;
		this.fecha = fecha;
	}
	
	public Remito() {
		itemsRemito = new LinkedList<ItemRemito>();
		this.estado = EstadoRemito.EMITIDO;
	}

	/*public Map<OrdenDePedido, List<ItemRemito>> getItemsPorOrdenDePedido() {
		Map<OrdenDePedido, List<ItemRemito>> itemsPorOP = Maps.newHashMap();
		
		for (ItemRemito item : itemsRemito) {
			OrdenDePedido o = item.getOrdenPedido();
			
			if (!itemsPorOP.containsKey(o)) {
				itemsPorOP.put(o, new LinkedList<ItemRemito>());
			}
			
			itemsPorOP.get(o).add(item);
		}
		
		return itemsPorOP;
	}*/

	public String getFecha() {
		return fecha;
	}

	public void setFecha(String fecha) {
		this.fecha = fecha;
	}

	public int getNumero() {
		return numero;
	}

	public void setNumero(int numero) {
		this.numero = numero;
	}

	public Cliente getCliente() {
		return cliente;
	}

	public void setCliente(Cliente cliente) {
		this.cliente = cliente;
	}

	public List<ItemRemito> getItemsRemito() {
		return itemsRemito;
	}

	public void setItemsRemito(List<ItemRemito> itemsRemito) {
		for(ItemRemito item : itemsRemito)
			item.setRem(this);
		this.itemsRemito = itemsRemito;
	}

	public EstadoRemito getEstado() {
		return estado;
	}

	public void setEstado(EstadoRemito estado) {
		this.estado = estado;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((cliente == null) ? 0 : cliente.hashCode());
		result = prime * result + ((estado == null) ? 0 : estado.hashCode());
		result = prime * result + ((fecha == null) ? 0 : fecha.hashCode());
		result = prime * result + ((itemsRemito == null) ? 0 : itemsRemito.hashCode());
		result = prime * result + numero;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Remito other = (Remito) obj;
		if (cliente == null) {
			if (other.cliente != null)
				return false;
		} else if (!cliente.equals(other.cliente))
			return false;
		if (estado != other.estado)
			return false;
		if (fecha == null) {
			if (other.fecha != null)
				return false;
		} else if (!fecha.equals(other.fecha))
			return false;
		if (itemsRemito == null) {
			if (other.itemsRemito != null)
				return false;
		} else if (!itemsRemito.equals(other.itemsRemito))
			return false;
		if (numero != other.numero)
			return false;
		return true;
	}

	@Override
	public String toString() {
		return "Remito [numero=" + numero + ", cliente=" + cliente + ", itemsRemito=" + itemsRemito + ", estado=" + estado
				+ ", fecha=" + fecha + "]";
	}
	
	public RemitoDTO toDTO (){
		RemitoDTO dto = new RemitoDTO();
		dto.setClienteDTO(cliente.toDTO());
		dto.setEstado(estado);
		dto.setFecha(fecha);
		dto.setNumero(numero);
		dto.setItemsRemito(listRemitoToDTO(itemsRemito));
		
		return dto;
	}
	
	public static Remito fromDTO (RemitoDTO dto){
		
		if(dto != null){
			Remito rem = new Remito(dto.getNumero(), new Cliente(dto.getClienteDTO()), dto.getEstado(), dto.getFecha());
			rem.setItemsRemito(listRemitofromDTO(dto.getItemsRemito()));
			return rem;
		
		}else
			return null;
	}
	
	
	private  List<ItemRemitoDTO> listRemitoToDTO(List<ItemRemito> lista){
		List<ItemRemitoDTO> dtoList = new LinkedList<ItemRemitoDTO>();
		
		for(ItemRemito item : lista){
			item.setRem(this);
			dtoList.add(item.toDTO());
		}
		
		return dtoList;
		
	}
	
	private static List<ItemRemito> listRemitofromDTO(List<ItemRemitoDTO> lista){
		List<ItemRemito> itemList = new LinkedList<ItemRemito>();
		
		for(ItemRemitoDTO item : lista){
			itemList.add(ItemRemito.fromDTO(item));
		}
		
		return itemList;
		
	}

}
